#!/usr/bin/python

import pprint
from sys import argv

# Some globals
diceSides = 10
debug = True

pp = pprint.PrettyPrinter(indent=4)

def getProbDicts(confDict):

    # Obtain a dict of all possible outcomes
    outcomesDict = getOutcomesDict(confDict["numDice"])

    # Walk the probabilities to determine the success against the given TN
    successDict = walkOutcomes(outcomesDict, confDict["tn"])

    # Now walk the successes to determine damage outcomes
    armor = confDict["armor"]
    power = confDict["power"]
    delta = confDict["damTn"]
    damageResultsDict = {}
    ''' Make the assumption that these results are multiplicative '''
    print "--------------- DOING ARMOR CALCS ---------------"
    for successes, percent in successDict.iteritems():
#        print "Evaluating successes %i @ %3.5f%%" % (successes, percent * 100.0)

        if successes == 0:
            if successes in damageResultsDict:
                damageResultsDict[successes] = damageResultsDict[successes] + percent
            else:
                damageResultsDict[successes] = percent
            continue
           
        damageOutcomes = getOutcomesDict(successes)
        damageSuccesses = walkOutcomes( damageOutcomes, delta )
        for boxes, boxPercent in damageSuccesses.iteritems():
            totalPercent = boxPercent * percent
#            print "Evaluated %i boxes as (%3.5f * %3.5f) = %3.5f" % (boxes, percent, boxPercent, totalPercent)
            if boxes in damageResultsDict:
                damageResultsDict[boxes] = damageResultsDict[boxes] + totalPercent
            else:
                damageResultsDict[boxes] = totalPercent
   
    print "--------------- SUMMARY ---------------"
    percentSum = 0.0
    for boxes, percent in damageResultsDict.iteritems():
        print "[%i] boxes occur %3.5f%%" % (boxes, percent * 100.0) 
        percentSum = percentSum + percent
    print "Total occurances: [%3.5f%%]" % (percentSum * 100)

"""
Walk the list of all outcomes from the initial
  test, and compose the number of successes
"""
def walkOutcomes(outcomesDict, targetNum):
   
    outcomes = float(len(outcomesDict))
    successDict = {} 
    for x in outcomesDict:
#        print "Checking x [%s]" % x
        # x is a list
        successCount = 0
        for y in x:
#            print "Checking value %i vs. %i" % (y, targetNum)
#            print "%i vs. targetNum %i < D%i" % (y, targetNum, diceSides)
            if y > diceSides:
                successCount = successCount+1
            elif y >= targetNum:
                successCount = successCount+1

 #       print "Raw success count is: %i" % successCount 

        if successCount in successDict:
            successDict[successCount].append(x)
        else:
            successDict[successCount] = [x]

    for x in successDict.iterkeys():
        succCount = len(successDict[x])
        #succPerc = ((succCount) / outcomes ) * 100.0
        succPerc = ((succCount) / outcomes ) 
        successDict[x] = succPerc
#        print "[%s] success were generated [%s] times, a %s%% chance." % (x, succCount, succPerc * 100.0)

    return successDict

def getOutcomesDict(numDice):
    outcomes = []

    for x in range(1, numDice+1):
        outcomes = appendDiceSides(outcomes, diceSides)

#    if debug:
#        pp.pprint(outcomes)

    return outcomes

def appendDiceSides(diceList, diceSides):

    if len(diceList) is 0:
        for x in range(1, diceSides+1):
            diceList.append([x])
        return diceList

    newList = []
    for y in diceList:
        # y is an element of list type
        for x in range(1, diceSides+1):
            z = y[:]
            z.append(x)
            newList.append(z)

    return newList

if __name__ == '__main__':
    confDict = {}
    numDice = 3
    if len(argv) >= 2:
        numDice = int(argv[1])
    confDict["numDice"] = numDice

    defense = 0
    if len(argv) >= 3:
        defense = int(argv[2])
    confDict["def"] = defense

    attack = 0
    if len(argv) >= 4:
        attack = int(argv[3])
    confDict["atk"] = attack

    targetNum = defense - attack
    if targetNum < 0:
        targetNum = 0
    confDict["tn"] = targetNum

    power = 0
    if len(argv) >= 5:
        power = int(argv[4])
    confDict["power"] = power

    armor = 0
    if len(argv) >= 6:
        armor = int(argv[5])
    confDict["armor"] = armor

    damTn = armor - power
    if damTn < 0:
        damTn = 0
    confDict["damTn"] = damTn
    

    print "Generating (%iD%i) vs. (RD %i - RA %i) = %i -> (POW %i vs. ARM %i) = %i" % \
        (numDice, diceSides, defense, attack, targetNum, power, armor, damTn)
    probDict = getProbDicts(confDict)

